package top.yangguangmc.sunshine_anticheat;

import org.bukkit.Bukkit;
import org.bukkit.command.PluginCommand;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import top.yangguangmc.sunshine_anticheat.api_impl.PlaceholderExpansionImpl;
import top.yangguangmc.sunshine_anticheat.check.Check;
import top.yangguangmc.sunshine_anticheat.check.CheckManager;
import top.yangguangmc.sunshine_anticheat.events.ServerTickEvent;
import top.yangguangmc.sunshine_anticheat.utils.Builtin;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * An open source anti-cheat plugin for spigot 1.8 by yangguangMC.
 *
 * @author yangguangMC
 * @version 1.0
 * @since 1.0
 */
public final class SunshineAntiCheat extends JavaPlugin {
    public static final String NAME = "SunshineAntiCheat";
    public static final String AUTHOR = "yangguangMC";
    public static final String VERSION = "1.0";
    private static Logger logger;

    private static SunshineAntiCheat instance;

    public static SunshineAntiCheat getInstance() {
        if (instance == null) throw new IllegalStateException("The plugin has not been loaded yet!");
        return instance;
    }

    private CheckManager checkManager;
    private ConfigManager configManager;
    private AlertManager alertManager;

    @Override
    public void onLoad() {
        instance = this;
        logger = getLogger();
        saveDefaultConfig();

        logger.info("Plugin loaded successfully.");
    }

    @Override
    public void onEnable() {
        logger.info("Welcome to " + NAME + " v" + VERSION + " by " + AUTHOR + "!");
        logger.info("Running on " + Bukkit.getName() + Bukkit.getVersion() + " (Bukkit: "
                + Bukkit.getBukkitVersion() + ", JRE " + System.getProperty("java.version") + ")");
        Builtin.ssac = this;
        Builtin.logger = getLogger();
        try {
            PluginCommand command = Bukkit.getPluginCommand("sunshineanticheat");
            CommandHandler commandHandler = new CommandHandler();
            command.setExecutor(commandHandler);
            command.setTabCompleter(commandHandler);
        } catch (Exception e) {
            logger.log(Level.SEVERE, "Cannot register command handler!", e);
            throw new RuntimeException(e);
        }

        if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI"))
            new PlaceholderExpansionImpl().register();
        if (!Bukkit.getPluginManager().isPluginEnabled("packetevents"))
            throw new RuntimeException("No PacketEventsAPI found!");

        checkManager = new CheckManager();
        configManager = new ConfigManager();
        alertManager = new AlertManager();
        checkManager.init();
        configManager.verifyConfig();
        configManager.load();

        if (isDebug()) {
            logger.warning("Debug mode is enabled! This is not recommend for general use!");
            logger.warning("To change this, set 'debug' to false in config.yml.");
        }

        new BukkitRunnable() {
            @Override
            public void run() {
                long tickIdOld = ServerTickEvent.tickId;
                ServerTickEvent.tickId = tickIdOld + 1;
                Bukkit.getPluginManager().callEvent(new ServerTickEvent());
            }
        }.runTaskTimer(this, 1, 0);

        logger.info("Plugin enabled successfully.");
    }

    @Override
    public void onDisable() {
        checkManager.getChecks().forEach(Check::onPluginDisable);
        instance = null;
        Builtin.ssac = null;
        Builtin.logger = null;
        logger.info("Plugin disabled successfully.");
    }

    /**
     * Gets a FileConfiguration for this plugin, read through "config.yml"
     * If there is a default config.yml embedded in this plugin,
     * it will be provided as a default for this Configuration.
     *
     * @deprecated Use methods of {@link ConfigManager} instead.
     */
    @SuppressWarnings("DeprecatedIsStillUsed")
    @Override
    @Deprecated
    public FileConfiguration getConfig() {
        return super.getConfig();
    }

    /**
     * Discards any data in getConfig() and reloads from disk.
     *
     * @deprecated Use methods of {@link ConfigManager} instead.
     */
    @SuppressWarnings("DeprecatedIsStillUsed")
    @Override
    @Deprecated
    public void reloadConfig() {
        super.reloadConfig();
    }

    public CheckManager getCheckManager() {
        return checkManager;
    }

    public ConfigManager getConfigManager() {
        return configManager;
    }

    public AlertManager getAlertManager() {
        return alertManager;
    }

    public String getPrefix() {
        return configManager.getString("plugin-prefix");
    }

    public boolean isDebug() {
        return configManager.getBoolean("debug");
    }

}
